

const defaultColumnTypeOption = {
  
  /**
   * @type { "text" | "number" | "date" 
   * | "tag" | "multiple" | "person" | "picture"
   * | "link" | "email" | "score" | "person" 
   * | "modification" | "select" }
   * @name type
   */
  type: "text",
  label: "文本",

  /** 创建元素 */
  createDom: () => {},
}

const serialColumnTypeOption = {
  type: "serial",
  label: "序号",
  createDom: (value) => {
    const span = document.createElement("span");
    span.className = "serial";
    span.textContent = value;
    return span;
  }
}

const tagTypeColumnTypeOption = {
  ...defaultColumnTypeOption,
  type: "tag",
  label: "标签",
  createDom: (value) => {
    const tag = document.createElement("span");
    tag.className = "tag";
    tag.textContent = value;
    return tag;
  },
}



// 自定义二维表
class Table {
  #table; // 实例
  #dom; // 表格容器
  #row; // 行数
  #col; // 列数
  #data; // 数据
  #editBox; // 编辑框
  #current; // 当前编辑的单元格

  /**
   * 列选项列表
   * @type {columnTypeOption[]}
   */
  #colTypeList = []; 

  constructor(row, col) {
    this.#row = row;
    this.#col = col;
    this.#data = new Array(row).fill(null).map(() => new Array(col).fill(null));
    this.table = this;
  }

  get data() {
    return this.#data;
  }

  addRow() {
    this.#row++;
    this.#data.push(new Array(this.#col).fill(null));
  }

  addCol() {
    this.#col++;
    for (let i = 0; i < this.#row; i++) {
      this.#data[i].push(null);
    }
  }

  setData(row, col, value) {
    this.#data[row][col] = value;
  }

  getData(row, col) {
    console.log(this.#data);
    return this.#data[row][col];
  }

  deleteRow() {
    const index = --this.#row;
    this.#data.splice(index, 1);
  }

  deleteCol() {
    const index = --this.#col;
    for (let i = 0; i < this.#row; i++) {
      this.#data[i].splice(index, 1);
    }
  }

  mount(dom) {
    this.#dom = dom;
    this.#dom.style.position = "relative";
  }

  render() {
    this.#dom.innerHTML = "";

    const table = document.createElement("table");

    // 创建表头

    for (let i = 0; i < this.#row; i++) {
      const row = document.createElement("tr");
      row.className = "row";
      row.dataset.row = `${i}`;

      const cell = document.createElement("td");
      const num = document.createElement("input");
      cell.className = "num";
      num.type = "checkbox";
      cell.appendChild(num);
      row.appendChild(cell);

      for (let j = 0; j < this.#col; j++) {

        // 创建单元格
        const cell = document.createElement("td");
        const item = document.createElement("div");

        cell.className = "cell";
        cell.dataset.position = `${i}-${j}`;
        item.className = "cell-item no-overflow-word";
        item.innerHTML = this.#data[i][j] || "";

        cell.appendChild(item);
        row.appendChild(cell);
      }

      table.appendChild(row);
    }

    this.#dom.appendChild(table);
  }

  printData(dom) {
    dom.querySelectorAll(".cell").forEach((cell) => {
      const [row, col] = cell.dataset.position.split("-").map(Number);
      cell.children[0].textContent = this.#data[row][col];
    });
  }

  handleListener() {
    this.initEditBox();
    this.listenCellClick();
  }

  initControl() {
    const buttons = document.querySelectorAll(".table-control.button");

    [...buttons].map((dom) => {
      const action = dom.textContent.toLowerCase();
      let type = "";

      if (action.startsWith("add")) {
        type = action.endsWith("row") ? "addRow" : "addCol";
      }
      if (action.startsWith("delete")) {
        type = action.endsWith("row") ? "deleteRow" : "deleteCol";
      }
      dom.addEventListener("click", () => {
        this[type]();
        this.render(this.#dom);
        this.handleListener();
      });
    });
  }

  listenCellClick() {
    this.#dom.addEventListener("click", (e) => {
      const target = e.target;
      if (!target.className.includes("cell")) return;

      this.#current = target;
      
      const value = target.textContent;
      const containerBoundary = this.#dom.getBoundingClientRect();
      const boundary = target.getBoundingClientRect();
      
      const positionX = boundary.left - containerBoundary.left;
      const positionY = boundary.top - containerBoundary.top;

      this.#editBox.style.left = `${positionX.toFixed(2)}px`;
      this.#editBox.style.top = `${positionY.toFixed(2)}px`;
      this.#editBox.style.width = `${boundary.width}px`;
      this.#editBox.style.height = `${boundary.height}px`;
      this.#editBox.style.display = "block";

      const input = this.#editBox.children[0].children[0];
      input.focus();
      input.value = value;
      input.selectionStart = 0;
      input.selectionEnd = 0;
      this.#editBox.style.opacity = 1;
    })
  }

  initEditBox() {
    const editBox = document.createElement("div");
    const inputWrap = document.createElement("div");
    const editBoxInput = document.createElement("input");
    editBox.style.opacity = 0;
    editBox.className = "edit-box";
    editBoxInput.className = "input-box no-overflow-word";
    editBoxInput.type = "input";
    inputWrap.appendChild(editBoxInput);
    editBox.appendChild(inputWrap);
    this.#editBox = editBox;
    this.#dom.appendChild(editBox);

    editBoxInput.addEventListener("blur", (e) => {
      const value = e.target.value;
      const [row, col] = this.#current.dataset.position.split("-").map(Number);
      this.#data[row][col] = value;
      this.#current.children[0].textContent = value;
    })
  }
}
